package pers.supeijin.devtools.converter.wx2vue.converter;

import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.css.impl.CssElementTypes;
import com.intellij.psi.css.impl.stubs.CssImportStubElementType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.xml.XmlTag;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import pers.supeijin.devtools.converter.base.BaseConverter;
import pers.supeijin.devtools.converter.utils.FilePathUtils;
import pers.supeijin.devtools.converter.utils.StringUtils;
import pers.supeijin.devtools.utils.GeneralContext;

//样式转换器
public class StyleConverter extends BaseConverter {
	private static final String LANG_TAG = "LANG_TAG";
	private static final String STYLE_TAG_TEXT = "<style scoped LANG_TAG>\t\n %s \t\n</style>";
	private static final String RPX_TAG = "rpx";
	private static final String PX_TAG = "px";
	private static final String STYLE_PAITH = "/src/commonStyle";
	private String mStylePath;
	private static HashMap<String, String> replaceExtensionsMap;

	static {
		replaceExtensionsMap = new HashMap<>();
		replaceExtensionsMap.put("wxss", "css");
		replaceExtensionsMap.put("ttss", "css");
		replaceExtensionsMap.put("acss", "css");
	}

	public StyleConverter(GeneralContext generalContext, VirtualFile styleFile) {
		super(generalContext, styleFile);
		mStylePath = mProject.getBasePath() + STYLE_PAITH;//公共样式存储目录
	}

	public XmlTag getStyleTag() {
		List<Pair<String, String>> styleList = getStyleList();
		String styleText = mPsiFile.getText();
		String styleLang = "";
		if (styleList.size() > 0) {
			String path = mGeneralContext.getVirtualFile().getPath();
			File baseFile = new File(path);
			for (Pair<String, String> pair : styleList) {
				File oldFile = getOldStyleFile(pair.first);
				if (oldFile != null) {
					if (styleLang.length() < 1) {
						styleLang = getStyleLang(oldFile);
					}
					File newFile = getNewStyleFile(oldFile);//转移后的目标文件
					String relativePath = FileUtil.getRelativePath(baseFile, newFile);
					relativePath = relativePath.replaceAll("\\\\", "/");
					styleText = styleText.replaceAll(pair.second, "\"" + relativePath + "\"");
					try {
						if (!newFile.exists()) {
							FileUtil.copy(oldFile, newFile);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		//替换单位 rpx->px
		styleText = StringUtils.replaceAll(styleText, RPX_TAG, PX_TAG);
		String formatText = String.format(STYLE_TAG_TEXT, styleText);
		formatText = formatText.replace(LANG_TAG, styleLang);
		return getXmlTag(formatText);
	}

	private String getStyleLang( File styleFile) {
		String extension = FileUtil.getExtension(styleFile.getName(), "").toString();
		String[] extensions=new String[]{"less","scss","sass"};///sass scss less
		List<String> strings = Arrays.asList(extensions);
		if (extension.length() > 1 && strings.contains(extension)) {
			StringBuilder sb = new StringBuilder();
			sb.append(" lang=\"")
					.append(extension)
					.append("\"");
			return sb.toString();
		}
		return "";
	}

	public File getNewStyleFile(File oldFile) {
		File file = new File(mStylePath);
		String newFileName = oldFile.getName();
		String extensionKey = FileUtil.getExtension(newFileName, "css").toString();
		String extensionName = replaceExtensionsMap.get(extensionKey);
		if (extensionName != null) {
			newFileName = FileUtil.getNameWithoutExtension(oldFile) + "." + extensionName;
		}
		String newFilePath = file.getPath() + File.separator + newFileName;
		return new File(newFilePath);
	}

	public File getOldStyleFile(String path) {
		String[] suffixs = new String[]{"", ".css", ".less", ".sass", ".scss", "wxss", "acss", "ttss"};
		for (int i = 0, len = suffixs.length; i < len; i++) {
			File oldFile = new File(path + suffixs[i]);
			if (oldFile.exists()) {
				return oldFile;
			}
		}
		return null;
	}

	public List<Pair<String, String>> getStyleList() {
		PsiElement[] cssImportList = getCssImportList();
		if (cssImportList != null && cssImportList.length>0) {
			return Arrays.stream(cssImportList)
					.map(element -> getElementInfo(element))
					.collect(Collectors.toList());
		}
		return new ArrayList<>();
	}

	private PsiElement[] getCssImportList() {
		//IElementType elementType = CssElementTypes.CSS_IMPORT_LIST;
		//IElementType elementType = CssElementTypes.CSS_IMPORT;
		return PsiTreeUtil.collectElements(mPsiFile, element -> {
			IElementType type = PsiUtilBase.getElementType(element);
			return type != null && type instanceof CssImportStubElementType && Objects.equals(CssElementTypes.CSS_IMPORT, type);
		});
	}

	private Pair<String, String> getElementInfo(PsiElement element) {
		String importText = FilePathUtils.getFilePathFromImportText(element.getText());
		String pathFromImportText = FilePathUtils.getFilePathFromImportText(importText);
		String relativePath = FilePathUtils.removeQuotationMarks(pathFromImportText);
		String filePath = FilePathUtils.getTargetFilePath(mVirtualFile.getPath(), relativePath);
		return new Pair(filePath, pathFromImportText);
	}
}
